/* =========================================================
 * Bootstrap year calendar v1.1.0
 * Repo: https://github.com/Paul-DS/bootstrap-year-calendar
 * =========================================================
 * Created by Paul David-Sivelle
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================= */

(function($) {
  var Calendar = function(element, options) {
    this.element = element;
    this.element.addClass('calendar');

    this._initializeEvents(options);
    this._initializeOptions(options);
    this._render();
  };

  Calendar.prototype = {
    constructor: Calendar,
    _initializeOptions: function(opt) {
      if(opt == null) {
        opt = [];
      }

      this.options = {
        startYear: !isNaN(parseInt(opt.startYear)) ? parseInt(opt.startYear) : new Date().getFullYear(),
        minDate: opt.minDate instanceof Date ? opt.minDate : null,
        maxDate: opt.maxDate instanceof Date ? opt.maxDate : null,
        language: (opt.language != null && dates[opt.language] != null) ? opt.language : 'en',
        allowOverlap: opt.allowOverlap != null ? opt.allowOverlap : true,
        displayWeekNumber: opt.displayWeekNumber != null ? opt.displayWeekNumber : false,
        alwaysHalfDay: opt.alwaysHalfDay != null ? opt.alwaysHalfDay : false,
        enableRangeSelection: opt.enableRangeSelection != null ? opt.enableRangeSelection : false,
        disabledDays: opt.disabledDays instanceof Array ? opt.disabledDays : [],
        roundRangeLimits: opt.roundRangeLimits != null ? opt.roundRangeLimits : false,
        dataSource: opt.dataSource instanceof Array != null ? opt.dataSource : [],
        style: opt.style == 'background' || opt.style == 'border' || opt.style == 'custom' ? opt.style : 'border',
        enableContextMenu: opt.enableContextMenu != null ? opt.enableContextMenu : false,
        contextMenuItems: opt.contextMenuItems instanceof Array ? opt.contextMenuItems : [],
        customDayRenderer : $.isFunction(opt.customDayRenderer) ? opt.customDayRenderer : null,
        customDataSourceRenderer : $.isFunction(opt.customDataSourceRenderer) ? opt.customDataSourceRenderer : null
      };

      this._initializeDatasourceColors();
    },
    _initializeEvents: function(opt) {
      if(opt == null) {
        opt = [];
      }

      if(opt.renderEnd) { this.element.bind('renderEnd', opt.renderEnd); }
      if(opt.clickDay) { this.element.bind('clickDay', opt.clickDay); }
      if(opt.dayContextMenu) { this.element.bind('dayContextMenu', opt.dayContextMenu); }
      if(opt.selectRange) { this.element.bind('selectRange', opt.selectRange); }
      if(opt.mouseOnDay) { this.element.bind('mouseOnDay', opt.mouseOnDay); }
      if(opt.mouseOutDay) { this.element.bind('mouseOutDay', opt.mouseOutDay); }
    },
    _initializeDatasourceColors: function() {
      for(var i in this.options.dataSource) {
        if(this.options.dataSource[i].color == null) {
          this.options.dataSource[i].color = colors[i % colors.length];
        }
      }
    },
    _render: function() {
      this.element.empty();

      this._renderHeader();
      this._renderBody();
      this._renderDataSource();

      this._applyEvents();
      this.element.find('.months-container').fadeIn(500);

      this._triggerEvent('renderEnd', { currentYear: this.options.startYear });
    },
    _renderHeader: function() {
      var header = $(document.createElement('div'));
      header.addClass('calendar-header panel panel-default');

      var headerTable = $(document.createElement('table'));

      var prevDiv = $(document.createElement('th'));
      prevDiv.addClass('prev');

      if(this.options.minDate != null && this.options.minDate > new Date(this.options.startYear - 1, 11, 31)) {
        prevDiv.addClass('disabled');
      }

      var prevIcon = $(document.createElement('span'));
      prevIcon.addClass('glyphicon glyphicon-chevron-left');

      prevDiv.append(prevIcon);

      headerTable.append(prevDiv);

      var prev2YearDiv = $(document.createElement('th'));
      prev2YearDiv.addClass('year-title year-neighbor2 hidden-sm hidden-xs');
      prev2YearDiv.text(this.options.startYear - 2);

      if(this.options.minDate != null && this.options.minDate > new Date(this.options.startYear - 2, 11, 31)) {
        prev2YearDiv.addClass('disabled');
      }

      headerTable.append(prev2YearDiv);

      var prevYearDiv = $(document.createElement('th'));
      prevYearDiv.addClass('year-title year-neighbor hidden-xs');
      prevYearDiv.text(this.options.startYear - 1);

      if(this.options.minDate != null && this.options.minDate > new Date(this.options.startYear - 1, 11, 31)) {
        prevYearDiv.addClass('disabled');
      }

      headerTable.append(prevYearDiv);

      var yearDiv = $(document.createElement('th'));
      yearDiv.addClass('year-title');
      yearDiv.text(this.options.startYear);

      headerTable.append(yearDiv);

      var nextYearDiv = $(document.createElement('th'));
      nextYearDiv.addClass('year-title year-neighbor hidden-xs');
      nextYearDiv.text(this.options.startYear + 1);

      if(this.options.maxDate != null && this.options.maxDate < new Date(this.options.startYear + 1, 0, 1)) {
        nextYearDiv.addClass('disabled');
      }

      headerTable.append(nextYearDiv);

      var next2YearDiv = $(document.createElement('th'));
      next2YearDiv.addClass('year-title year-neighbor2 hidden-sm hidden-xs');
      next2YearDiv.text(this.options.startYear + 2);

      if(this.options.maxDate != null && this.options.maxDate < new Date(this.options.startYear + 2, 0, 1)) {
        next2YearDiv.addClass('disabled');
      }

      headerTable.append(next2YearDiv);

      var nextDiv = $(document.createElement('th'));
      nextDiv.addClass('next');

      if(this.options.maxDate != null && this.options.maxDate < new Date(this.options.startYear + 1, 0, 1)) {
        nextDiv.addClass('disabled');
      }

      var nextIcon = $(document.createElement('span'));
      nextIcon.addClass('glyphicon glyphicon-chevron-right');

      nextDiv.append(nextIcon);

      headerTable.append(nextDiv);

      header.append(headerTable);

      this.element.append(header);
    },
    _renderBody: function() {
      var monthsDiv = $(document.createElement('div'));
      monthsDiv.addClass('months-container');
      let currentMonth = null;
      let length = null;
      // 展示时间周期不同
      if (localStorage.allCalendar === 'true') {
        currentMonth = 0;
        length = 12;
      } else {
        currentMonth = new Date().getMonth() -1;
        length = currentMonth + 6
      }
      for(var m = currentMonth; m < length; m++) {
        /* Container */
        var monthDiv = $(document.createElement('div'));
        monthDiv.addClass('month-container');
        monthDiv.data('month-id', m);
        var firstDate = new Date(this.options.startYear, m, 1);

        var table = $(document.createElement('table'));
        table.addClass('month');

        /* Month header */
        var thead = $(document.createElement('thead'));

        var titleRow = $(document.createElement('tr'));

        var titleCell = $(document.createElement('th'));
        titleCell.addClass('month-title');
        titleCell.attr('colspan', this.options.displayWeekNumber ? 8 : 7);
        titleCell.text(dates[this.options.language].months[m]);

        titleRow.append(titleCell);
        thead.append(titleRow);

        var headerRow = $(document.createElement('tr'));

        if(this.options.displayWeekNumber) {
          var weekNumberCell = $(document.createElement('th'));
          weekNumberCell.addClass('week-number');
          weekNumberCell.text(dates[this.options.language].weekShort);
          headerRow.append(weekNumberCell);
        }

        var d = dates[this.options.language].weekStart;
        do
        {
          var headerCell = $(document.createElement('th'));
          headerCell.addClass('day-header');
          headerCell.text(dates[this.options.language].daysMin[d]);

          headerRow.append(headerCell);

          d++;
          if(d >= 7)
            d = 0;
        }
        while(d != dates[this.options.language].weekStart)

        thead.append(headerRow);
        table.append(thead);

        /* Days */
        var currentDate = new Date(firstDate.getTime());
        var lastDate = new Date(this.options.startYear, m + 1, 0);

        var weekStart = dates[this.options.language].weekStart

        while(currentDate.getDay() != weekStart)
        {
          currentDate.setDate(currentDate.getDate() - 1);
        }

        while(currentDate <= lastDate)
        {
          var row = $(document.createElement('tr'));

          if(this.options.displayWeekNumber) {
            var weekNumberCell = $(document.createElement('td'));
            weekNumberCell.addClass('week-number');
            weekNumberCell.text(this.getWeekNumber(currentDate));
            row.append(weekNumberCell);
          }

          do
          {
            var cell = $(document.createElement('td'));
            cell.addClass('day');

            if(currentDate < firstDate) {
              cell.addClass('old');
            }
            else if(currentDate > lastDate) {
              cell.addClass('new');
            }
            else {
              if((this.options.minDate != null && currentDate < this.options.minDate) || (this.options.maxDate != null && currentDate > this.options.maxDate))
              {
                cell.addClass('disabled');
              }
              else if(this.options.disabledDays.length > 0) {
                for(var d in this.options.disabledDays){
                  if(currentDate.getTime() == this.options.disabledDays[d].getTime()) {
                    cell.addClass('disabled');
                    break;
                  }
                }
              }

              var cellContent = $(document.createElement('div'));
              cellContent.addClass('day-content');
              cellContent.text(currentDate.getDate());
              cell.append(cellContent);

              if(this.options.customDayRenderer) {
                this.options.customDayRenderer(cellContent, currentDate);
              }
            }

            row.append(cell);

            currentDate.setDate(currentDate.getDate() + 1);
          }
          while(currentDate.getDay() != weekStart)

          table.append(row);
        }

        monthDiv.append(table);

        monthsDiv.append(monthDiv);
      }

      this.element.append(monthsDiv);
    },
    _renderDataSource: function() {
      var _this = this;
      if(this.options.dataSource != null && this.options.dataSource.length > 0) {
        this.element.find('.month-container').each(function() {
          var month = $(this).data('month-id');

          var firstDate = new Date(_this.options.startYear, month, 1);
          var lastDate = new Date(_this.options.startYear, month + 1, 0);

          if((_this.options.minDate == null || lastDate >= _this.options.minDate) && (_this.options.maxDate == null || firstDate <= _this.options.maxDate))
          {
            var monthData = [];

            for(var i in _this.options.dataSource) {
              if(!(_this.options.dataSource[i].startDate > lastDate) || (_this.options.dataSource[i].endDate < firstDate)) {
                monthData.push(_this.options.dataSource[i]);
              }
            }

            if(monthData.length > 0) {
              $(this).find('.day-content').each(function() {
                var currentDate = new Date(_this.options.startYear, month, $(this).text());

                var dayData = [];

                if((_this.options.minDate == null || currentDate >= _this.options.minDate) && (_this.options.maxDate == null || currentDate <= _this.options.maxDate))
                {
                  for(var i in monthData) {
                    if(monthData[i].startDate <= currentDate && monthData[i].endDate >= currentDate) {
                      dayData.push(monthData[i]);
                    }
                  }

                  if(dayData.length > 0)
                  {
                    _this._renderDataSourceDay($(this), currentDate, dayData);
                  }
                }
              });
            }
          }
        });
      }
    },
    _renderDataSourceDay: function(elt, currentDate, events) {
      switch(this.options.style)
      {
        case 'border':
          var weight = 0;

          if(events.length == 1) {
            weight = 4;
          }
          else if(events.length <= 3) {
            weight = 2;
          }
          else {
            elt.parent().css('box-shadow', 'inset 0 -4px 0 0 black');
          }

          if(weight > 0)
          {
            var boxShadow = '';

            for(var i in events)
            {
              if(boxShadow != '') {
                boxShadow += ",";
              }

              boxShadow += 'inset 0 -' + (parseInt(i) + 1) * weight + 'px 0 0 ' + events[i].color;
            }

            elt.parent().css('box-shadow', boxShadow);
          }
          break;

        case 'background':
          elt.parent().css('background-color', events[events.length - 1].color);

          var currentTime = currentDate.getTime();

          if(events[events.length - 1].startDate.getTime() == currentTime)
          {
            elt.parent().addClass('day-start');

            if(events[events.length - 1].startHalfDay || this.options.alwaysHalfDay) {
              elt.parent().addClass('day-half');

              // Find color for other half
              var otherColor = 'transparent';
              for(var i = events.length - 2; i >= 0; i--) {
                if(events[i].startDate.getTime() != currentTime || (!events[i].startHalfDay && !this.options.alwaysHalfDay)) {
                  otherColor = events[i].color;
                  break;
                }
              }

              elt.parent().css('background', 'linear-gradient(-45deg, ' + events[events.length - 1].color + ', ' + events[events.length - 1].color + ' 49%, ' + otherColor + ' 51%, ' + otherColor + ')');
            }
            else if(this.options.roundRangeLimits) {
              elt.parent().addClass('round-left');
            }
          }
          else if(events[events.length - 1].endDate.getTime() == currentTime)
          {
            elt.parent().addClass('day-end');

            if(events[events.length - 1].endHalfDay || this.options.alwaysHalfDay) {
              elt.parent().addClass('day-half');

              // Find color for other half
              var otherColor = 'transparent';
              for(var i = events.length - 2; i >= 0; i--) {
                if(events[i].endDate.getTime() != currentTime || (!events[i].endHalfDay &&  !this.options.alwaysHalfDay)) {
                  otherColor = events[i].color;
                  break;
                }
              }

              elt.parent().css('background', 'linear-gradient(135deg, ' + events[events.length - 1].color + ', ' + events[events.length - 1].color + ' 49%, ' + otherColor + ' 51%, ' + otherColor + ')');
            }
            else if(this.options.roundRangeLimits) {
              elt.parent().addClass('round-right');
            }
          }
          break;

        case 'custom':
          if(this.options.customDataSourceRenderer) {
            this.options.customDataSourceRenderer.call(this, elt, currentDate, events);
          }
          break;
      }
    },
    _applyEvents: function () {
      var _this = this;

      /* Header buttons */
      this.element.find('.year-neighbor, .year-neighbor2').click(function() {
        if(!$(this).hasClass('disabled')) {
          _this.setYear(parseInt($(this).text()));
        }
      });

      this.element.find('.calendar-header .prev').click(function() {
        if(!$(this).hasClass('disabled')) {
          _this.element.find('.months-container').animate({'margin-left':'100%'},100, function() {
            _this.element.find('.months-container').hide();
            _this.element.find('.months-container').css('margin-left', '0');
            setTimeout(function() { _this.setYear(_this.options.startYear - 1) }, 50);
          });
        }
      });

      this.element.find('.calendar-header .next').click(function() {
        if(!$(this).hasClass('disabled')) {
          _this.element.find('.months-container').animate({'margin-left':'-100%'},100, function() {
            _this.element.find('.months-container').hide();
            _this.element.find('.months-container').css('margin-left', '0');
            setTimeout(function() { _this.setYear(_this.options.startYear + 1) }, 50);
          });
        }
      });

      var cells = this.element.find('.day:not(.old, .new, .disabled)');

      /* Click on date */
      cells.click(function(e) {
        e.stopPropagation();
        var date = _this._getDate($(this));
        _this._triggerEvent('clickDay', {
          element: $(this),
          which: e.which,
          date: date,
          events: _this.getEvents(date)
        });
      });

      /* Click right on date */

      cells.bind('contextmenu', function(e) {
        if(_this.options.enableContextMenu)
        {
          e.preventDefault();
          if(_this.options.contextMenuItems.length > 0)
          {
            _this._openContextMenu($(this));
          }
        }

        var date = _this._getDate($(this));
        _this._triggerEvent('dayContextMenu', {
          element: $(this),
          date: date,
          events: _this.getEvents(date)
        });
      });

      /* Range selection */
      if(this.options.enableRangeSelection) {
        cells.mousedown(function (e) {
          if(e.which == 1) {
            var currentDate = _this._getDate($(this));

            if(_this.options.allowOverlap || _this.getEvents(currentDate).length == 0)
            {
              _this._mouseDown = true;
              _this._rangeStart = _this._rangeEnd = currentDate;
              _this._refreshRange();
            }
          }
        });

        cells.mouseenter(function (e) {
          if (_this._mouseDown) {
            var currentDate = _this._getDate($(this));

            if(!_this.options.allowOverlap)
            {
              var newDate =  new Date(_this._rangeStart.getTime());

              if(newDate < currentDate) {
                var nextDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate() + 1);
                while(newDate < currentDate) {
                  if(_this.getEvents(nextDate).length > 0)
                  {
                    break;
                  }

                  newDate.setDate(newDate.getDate() + 1);
                  nextDate.setDate(nextDate.getDate() + 1);
                }
              }
              else {
                var nextDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate() - 1);
                while(newDate > currentDate) {
                  if(_this.getEvents(nextDate).length > 0)
                  {
                    break;
                  }

                  newDate.setDate(newDate.getDate() - 1);
                  nextDate.setDate(nextDate.getDate() - 1);
                }
              }

              currentDate = newDate;
            }

            var oldValue = _this._rangeEnd;
            _this._rangeEnd = currentDate;

            if (oldValue.getTime() != _this._rangeEnd.getTime()) {
              _this._refreshRange();
            }
          }
        });

        $(window).mouseup(function (e) {
          if (_this._mouseDown) {
            _this._mouseDown = false;
            _this._refreshRange();

            var minDate = _this._rangeStart < _this._rangeEnd ? _this._rangeStart : _this._rangeEnd;
            var maxDate = _this._rangeEnd > _this._rangeStart ? _this._rangeEnd : _this._rangeStart;

            _this._triggerEvent('selectRange', { startDate: minDate, endDate: maxDate });
          }
        });
      }

      /* Hover date */
      cells.mouseenter(function(e) {
        if(!_this._mouseDown)
        {
          var date = _this._getDate($(this));
          _this._triggerEvent('mouseOnDay', {
            element: $(this),
            date: date,
            events: _this.getEvents(date)
          });
        }
      });

      cells.mouseleave(function(e) {
        var date = _this._getDate($(this));
        _this._triggerEvent('mouseOutDay', {
          element: $(this),
          date: date,
          events: _this.getEvents(date)
        });
      });

      /* Responsive management */

      setInterval(function() {
        var calendarSize = $(_this.element).width();
        var monthSize = $(_this.element).find('.month').first().width() + 10;
        var monthContainerClass = 'month-container';

        if(monthSize * 6 < calendarSize) {
          monthContainerClass += ' col-xs-2';
        }
        else if(monthSize * 4 < calendarSize) {
          monthContainerClass += ' col-xs-3';
        }
        else if(monthSize * 3 < calendarSize) {
          monthContainerClass += ' col-xs-4';
        }
        else if(monthSize * 2 < calendarSize) {
          monthContainerClass += ' col-xs-6';
        }
        else {
          monthContainerClass += ' col-xs-12';
        }

        $(_this.element).find('.month-container').attr('class', monthContainerClass);
      }, 300);
    },
    _refreshRange: function () {
      var _this = this;

      this.element.find('td.day.range').removeClass('range')
      this.element.find('td.day.range-start').removeClass('range-start');
      this.element.find('td.day.range-end').removeClass('range-end');

      if (this._mouseDown) {
        var beforeRange = true;
        var afterRange = false;
        var minDate = _this._rangeStart < _this._rangeEnd ? _this._rangeStart : _this._rangeEnd;
        var maxDate = _this._rangeEnd > _this._rangeStart ? _this._rangeEnd : _this._rangeStart;

        this.element.find('.month-container').each(function () {
          var monthId = $(this).data('month-id');
          if (minDate.getMonth() <= monthId && maxDate.getMonth() >= monthId) {
            $(this).find('td.day:not(.old, .new)').each(function () {
              var date = _this._getDate($(this));
              if (date >= minDate && date <= maxDate) {
                $(this).addClass('range');

                if (date.getTime() == minDate.getTime()) {
                  $(this).addClass('range-start');
                }

                if (date.getTime() == maxDate.getTime()) {
                  $(this).addClass('range-end');
                }
              }
            });
          }
        });
      }
    },
    _openContextMenu: function(elt) {
      var contextMenu = $('.calendar-context-menu');

      if(contextMenu.length > 0) {
        contextMenu.hide();
        contextMenu.empty();
      }
      else {
        contextMenu = $(document.createElement('div'));
        contextMenu.addClass('calendar-context-menu');
        $('body').append(contextMenu);
      }

      var date = this._getDate(elt);
      var events = this.getEvents(date);

      for(var i in events) {
        var eventItem = $(document.createElement('div'));
        eventItem.addClass('item');
        eventItem.css('border-left', '4px solid ' + events[i].color);

        var eventItemContent = $(document.createElement('div'));
        eventItemContent.addClass('content');
        eventItemContent.text(events[i].name);

        eventItem.append(eventItemContent);

        var icon = $(document.createElement('span'));
        icon.addClass('glyphicon glyphicon-chevron-right');

        eventItem.append(icon);

        this._renderContextMenuItems(eventItem, this.options.contextMenuItems, events[i]);

        contextMenu.append(eventItem);
      }

      if(contextMenu.children().length > 0)
      {
        contextMenu.css('left', elt.offset().left + 25 + 'px');
        contextMenu.css('top', elt.offset().top + 25 + 'px');
        contextMenu.show();

        $(window).one('mouseup', function() {
          contextMenu.hide();
        });
      }
    },
    _renderContextMenuItems: function(parent, items, evt) {
      var subMenu = $(document.createElement('div'));
      subMenu.addClass('submenu');

      for(var i in items) {
        if(!items[i].visible || items[i].visible(evt)) {
          var menuItem = $(document.createElement('div'));
          menuItem.addClass('item');

          var menuItemContent = $(document.createElement('div'));
          menuItemContent.addClass('content');
          menuItemContent.text(items[i].text);

          menuItem.append(menuItemContent);

          if(items[i].click) {
            (function(index) {
              menuItem.click(function() {
                items[index].click(evt);
              });
            })(i);
          }

          var icon = $(document.createElement('span'));
          icon.addClass('glyphicon glyphicon-chevron-right');

          menuItem.append(icon);

          if(items[i].items && items[i].items.length > 0) {
            this._renderContextMenuItems(menuItem, items[i].items, evt);
          }

          subMenu.append(menuItem);
        }
      }

      if(subMenu.children().length > 0)
      {
        parent.append(subMenu);
      }
    },
    _getColor: function(colorString) {
      var div = $('<div />');
      div.css('color', colorString);

    },
    _getDate: function(elt) {
      var day = elt.children('.day-content').text();
      var month = elt.closest('.month-container').data('month-id');
      var year = this.options.startYear;

      return new Date(year, month, day);
    },
    _triggerEvent: function(eventName, parameters) {
      var event = $.Event(eventName);

      for(var i in parameters) {
        event[i] = parameters[i];
      }

      this.element.trigger(event);
    },
    getWeekNumber: function(date) {
      var tempDate = new Date(date.getTime());
      tempDate.setHours(0, 0, 0, 0);
      tempDate.setDate(tempDate.getDate() + 3 - (tempDate.getDay() + 6) % 7);
      var week1 = new Date(tempDate.getFullYear(), 0, 4);
      return 1 + Math.round(((tempDate.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
    },
    getEvents: function(date) {
      var events = [];

      if(this.options.dataSource && date) {
        for(var i in this.options.dataSource) {
          if(this.options.dataSource[i].startDate <= date && this.options.dataSource[i].endDate >= date) {
            events.push(this.options.dataSource[i]);
          }
        }
      }

      return events;
    },
    getYear: function() {
      return this.options.startYear;
    },
    setYear: function(year) {
      var parsedYear = parseInt(year);
      if(!isNaN(parsedYear)) {
        this.options.startYear = parsedYear;
        this._render();
      }
    },
    getMinDate: function() {
      return this.options.minDate;
    },
    setMinDate: function(date) {
      if(date instanceof Date) {
        this.options.minDate = date;
        this._render();
      }
    },
    getMaxDate: function() {
      return this.options.maxDate;
    },
    setMaxDate: function(date) {
      if(date instanceof Date) {
        this.options.maxDate = date;
        this._render();
      }
    },
    getStyle: function() {
      return this.options.style;
    },
    setStyle: function(style) {
      this.options.style = style == 'background' || style == 'border' || style == 'custom' ? style : 'border';
      this._render();
    },
    getAllowOverlap: function() {
      return this.options.allowOverlap;
    },
    setAllowOverlap: function(allowOverlap) {
      this.options.allowOverlap = allowOverlap;
    },
    getDisplayWeekNumber: function() {
      return this.options.displayWeekNumber;
    },
    setDisplayWeekNumber: function(displayWeekNumber) {
      this.options.displayWeekNumber = displayWeekNumber;
      this._render();
    },
    getAlwaysHalfDay: function() {
      return this.options.alwaysHalfDay;
    },
    setAlwaysHalfDay: function(alwaysHalfDay) {
      this.options.alwaysHalfDay = alwaysHalfDay;
      this._render();
    },
    getEnableRangeSelection: function() {
      return this.options.enableRangeSelection;
    },
    setEnableRangeSelection: function(enableRangeSelection) {
      this.options.enableRangeSelection = enableRangeSelection;
      this._render();
    },
    getDisabledDays: function() {
      return this.options.disabledDays;
    },
    setDisabledDays: function(disabledDays) {
      this.options.disabledDays = disabledDays instanceof Array ? disabledDays : [];
      this._render();
    },
    getRoundRangeLimits: function() {
      return this.options.roundRangeLimits;
    },
    setRoundRangeLimits: function(roundRangeLimits) {
      this.options.roundRangeLimits = roundRangeLimits;
      this._render();
    },
    getEnableContextMenu: function() {
      return this.options.enableContextMenu;
    },
    setEnableContextMenu: function(enableContextMenu) {
      this.options.enableContextMenu = enableContextMenu;
      this._render();
    },
    getContextMenuItems: function() {
      return this.options.contextMenuItems;
    },
    setContextMenuItems: function(contextMenuItems) {
      this.options.contextMenuItems = contextMenuItems instanceof Array ? contextMenuItems : [];
      this._render();
    },
    getCustomDayRenderer: function() {
      return this.options.customDayRenderer;
    },
    setCustomDayRenderer: function(customDayRenderer) {
      this.options.customDayRenderer = $.isFunction(customDayRenderer) ? customDayRenderer : null;
      this._render();
    },
    getCustomDataSourceRenderer: function() {
      return this.options.customDataSourceRenderer;
    },
    setCustomDataSourceRenderer: function(customDataSourceRenderer) {
      this.options.customDataSourceRenderer = $.isFunction(customDataSourceRenderer) ? customDataSourceRenderer : null;
      this._render();
    },
    getLanguage: function() {
      return this.options.language;
    },
    setLanguage: function(language) {
      if(language != null && dates[language] != null) {
        this.options.language = language;
        this._render();
      }
    },
    getDataSource: function() {
      return this.options.dataSource;
    },
    setDataSource: function(dataSource) {
      this.options.dataSource = dataSource instanceof Array ? dataSource : [];
      this._initializeDatasourceColors();
      this._render();
    },
    addEvent: function(evt) {
      this.options.dataSource.push(evt);
      this._render();
    }
  }

  $.fn.calendar = function (options) {
    var calendar = new Calendar($(this) ,options);
    $(this).data('calendar', calendar);
    return calendar;
  }

  /* Events binding management */
  $.fn.renderEnd = function(fct) { $(this).bind('renderEnd', fct); }
  $.fn.clickDay = function(fct) { $(this).bind('clickDay', fct); }
  $.fn.dayContextMenu = function(fct) { $(this).bind('dayContextMenu', fct); }
  $.fn.selectRange = function(fct) { $(this).bind('selectRange', fct); }
  $.fn.mouseOnDay = function(fct) { $(this).bind('mouseOnDay', fct); }
  $.fn.mouseOutDay = function(fct) { $(this).bind('mouseOutDay', fct); }

  // var dates = $.fn.calendar.dates = {
  //   en: {
  //     days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
  //     daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  //     daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
  //     months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  //     monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
  //     weekShort: 'W',
  //     weekStart:0
  //   }
  // };
  //
  // var colors = $.fn.calendar.colors = ['#2C8FC9', '#9CB703', '#F5BB00', '#FF4A32', '#B56CE2', '#45A597'];
  var dates = $.fn.calendar.dates = {
    en: {
      days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
      daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"],
      months: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
      monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
      weekShort: 'W',
      weekStart: 0
    }
  };

  var colors = $.fn.calendar.colors = ['#EA5A49', '#4A90E2', '#44CC00', '#FFBD17', '#11C1F3', '#484746'];

  $(function(){
    $('[data-provide="calendar"]').each(function() {
      $(this).calendar();
    });
  });
}(window.jQuery));
